/**
 * rec 1.0.1 改版引入的 websocket 事件处理函数
 * 😭 其实怎么写都会有bug的，要无bug只能在后端做录音权限分发，还得用长链接监听用户异常下线。
 */
import { message } from 'antd';
import events from '@/utils/eventBus';
import EVENTBUS_TYPES from '@/pages/Recruitment/Interview/utils/EVENTBUS_TYPES';
import WEBSOCKET_TYPES from './WEBSOCKET_TYPES';

/**
 * 展示 message
 * @param {*} msgType success warning error
 * @param {*} msg 内容
 */
const showMessageHandler = (msgType, msg, remoteUserCode, myUserCode) => {
    if (remoteUserCode === myUserCode) return;
    if (msgType === 'success') {
        message.success(msg);
    }
};

/**
 * 被动触发的上线事件 --- 在收到 isPassive 为 false 的 ONLINE 事件时，发出,告知其他用户，自己的在线状态。
 * 如果自己是主录音者，且在录音，同时同步时间戳
 * state 主录音状态
 * durationMS 主录音毫秒
 */
const passiveTriggerOnlineEvent = (localWsRef, user, isHost, state, durationMS, remoteRECState, recHOSTuserCode) => {
    const data = { userCode: user, isPassive: true, timeStamp: isHost && state === 1 ? durationMS : null };
    if (isHost) {
        data.isHost = isHost;
    }
    if (isHost && remoteRECState === 2) {
        // 本人是主录音，且已暂停的情况下。携带这个字段
        data.hostPaused = true;
    }
    if (!isHost && remoteRECState === 2) {
        // 针对主录音异常掉线后又重新上线的情况。
        data.lastHost = recHOSTuserCode;
    }
    const msg = {
        type: WEBSOCKET_TYPES.ONLINE,
        data // 带上上一个主录音者的userCode
    };

    if (localWsRef.current && localWsRef.current.current) {
        localWsRef.current.current.send(msg);
    } else {
        console.log('无法获取ws实例');
    }
};

let timestampOfFight = 0; // 本地发起主录音权限争夺的时间
const agreeArr = []; // 赞同本人获取主录音权限者
let allowFightForHost = false; // 是否允许争夺主录音权限
let hostTimmer = null; // 判断争夺主录音权限超时用的

/**
 * 发起主录音争夺
 */
const startFightForHost = (localWsRef, user, onlineListRef) => {
    timestampOfFight = Date.now();
    agreeArr.length = 0; // 情况同意的数组
    allowFightForHost = true;
    if (localWsRef.current && localWsRef.current.current) {
        localWsRef.current.current.send({
            type: WEBSOCKET_TYPES.FIGHT_FOR_HOST,
            data: { userCode: user, timeStamp: timestampOfFight }
        });
        hostTimmer = setTimeout(() => {
            // 3秒未获取到争夺到主录音授权，则主动取消
            if (onlineListRef.current.length !== agreeArr.length) {
                allowFightForHost = false;
                message.warning('主录音权限获取失败，请重试');
                events.emit(EVENTBUS_TYPES.SET_BLOCK, false);
            }
        }, 3000);
    } else {
        events.emit(EVENTBUS_TYPES.SET_BLOCK, false);
        console.log('无法获取ws实例');
    }
};

/**
 * 处理别人发起的主录音争夺的事件，自己发的也做回应，用于应对只有一个人上线的情况
 */
const handleFightEvent = (localWsRef, user, wsRes) => {
    let isAgree = false;
    if (wsRes.data.timeStamp <= timestampOfFight || timestampOfFight === 0) {
        isAgree = true;
    }
    if (localWsRef.current && localWsRef.current.current) {
        localWsRef.current.current.send({
            type: WEBSOCKET_TYPES.RESPONSE_FOR_FIGHT,
            data: { userCode: user, targetUser: wsRes.data.userCode, isAgree }
        });
    } else {
        console.log('无法获取ws实例');
    }
};

/**
 * 处理针对主录音争夺的响应
 */
const handleResponseForFight = (localWsRef, user, onlineListRef, wsRes, recHOSTuserCodeRef) => {
    if (!allowFightForHost || wsRes.data.targetUser !== user || agreeArr.includes(wsRes.data.userCode)) {
        // 非针对本人的请求，或是已经在同意数组中,或已超时导致不允许争夺主录音
        return;
    }
    if (!wsRes.data.isAgree) {
        // 有人不同意
        clearTimeout(hostTimmer);
        events.emit(EVENTBUS_TYPES.HOST_FIGHT_RESULT, false);
        events.emit(EVENTBUS_TYPES.SET_BLOCK, false);
        agreeArr.length = 0;
        timestampOfFight = 0;
    }
    agreeArr.push(wsRes.data.userCode); // 把同意者推入数组
    if (onlineListRef.current.length === agreeArr.length) {
        // 所有在线者都同意
        clearTimeout(hostTimmer);
        console.log('%c所有在线者都同意!!!!! 启动录音！', 'color: red;');
        timestampOfFight = 0;
        events.emit(EVENTBUS_TYPES.HOST_FIGHT_RESULT, true); // 启动本地录音
        events.emit(EVENTBUS_TYPES.SET_BLOCK, false);
        recHOSTuserCodeRef.current = user;
        if (localWsRef.current && localWsRef.current.current) {
            localWsRef.current.current.send({
                // 发送主录音USERCODE到各端，录音成功启动后，再发送录音启动事件
                type: WEBSOCKET_TYPES.SET_HOST,
                userCode: user
            });
        } else {
            console.log('无法获取ws实例');
        }
    }
};

export { showMessageHandler, passiveTriggerOnlineEvent, startFightForHost, handleFightEvent, handleResponseForFight };
